/**
 * 
 */
package com.radeonsys.litmus.data.converters;

import java.util.HashMap;
import java.util.Map;


/**
 * Helper class that provides {@link Converter} implementations that convert from
 * string values to basic data types.
 * 
 * @author Ranganath Kini (ranganathkini at gmail dot com)
 * @version 1.0
 */
public class StringConverters {
	
	// stores the converters
	private static final Map<Class<?>, Converter<String, ?>> converterMap = 
		new HashMap<Class<?>, Converter<String, ?>>();
	
	static {
		// register converter for java.lang.Byte
		converterMap.put(Byte.class, new Converter<String, Byte>() {
			public Byte convert(final String value) {
				return Byte.parseByte(value);
			}
		});
		
		// register converter for java.lang.Short
		converterMap.put(Short.class, new Converter<String, Short>() {
			public Short convert(final String value) {
				return Short.parseShort(value);
			}
		});
		
		// register converter for java.lang.Integer
		converterMap.put(Integer.class, new Converter<String, Integer>() {
			public Integer convert(final String value) {
				return Integer.parseInt(value);
			}
		});
		
		// register converter for java.lang.Long
		converterMap.put(Long.class, new Converter<String, Long>() {
			public Long convert(final String value) {
				return Long.parseLong(value);
			}
		});
		
		// register converter for java.lang.Float
		converterMap.put(Float.class, new Converter<String, Float>() {
			public Float convert(final String value) {
				return Float.parseFloat(value);
			}
		});
		
		// register converter for java.lang.Double
		converterMap.put(Double.class, new Converter<String, Double>() {
			public Double convert(final String value) {
				return Double.parseDouble(value);
			}
		});
		
		// register converter for java.lang.Boolean
		converterMap.put(Boolean.class, new Converter<String, Boolean>() {
			public Boolean convert(final String value) {
				return Boolean.parseBoolean(value);
			}
		});
		
		// register converter for java.lang.Character
		converterMap.put(Character.class, new Converter<String, Character>() {
			public Character convert(final String value) {
				return value.charAt(0);
			}
		});
		
		// register converter for java.lang.String
		converterMap.put(String.class, new Converter<String, String>() {
			public String convert(final String value) {
				return value;
			}
		});
	}
	
	/**
	 * Returns an implementation of {@link Converter} which converts a 
	 * {@link String} to a {@link Byte}
	 */
	public static final Converter<String, Byte> BYTE = getConverterFor(Byte.class);
	
	/**
	 * Returns an implementation of {@link Converter} which converts a 
	 * {@link String} to a {@link Short}
	 */
	public static final Converter<String, Short> SHORT = getConverterFor(Short.class);
	
	/**
	 * Returns an implementation of {@link Converter} which converts a 
	 * {@link String} to a {@link Integer}
	 */
	public static final Converter<String, Integer> INTEGER = getConverterFor(Integer.class);;
	
	/**
	 * Returns an implementation of {@link Converter} which converts a 
	 * {@link String} to a {@link Long}
	 */
	public static final Converter<String, Long> LONG = getConverterFor(Long.class);;
	
	/**
	 * Returns an implementation of {@link Converter} which converts a 
	 * {@link String} to a {@link Float}
	 */
	public static final Converter<String, Float> FLOAT = getConverterFor(Float.class);
	
	/**
	 * Returns an implementation of {@link Converter} which converts a 
	 * {@link String} to a {@link Double}
	 */
	public static final Converter<String, Double> DOUBLE = getConverterFor(Double.class);
	
	/**
	 * Returns an implementation of {@link Converter} which converts a 
	 * {@link String} to a {@link Boolean}
	 */
	public static final Converter<String, Boolean> BOOLEAN = getConverterFor(Boolean.class);
	
	/**
	 * Returns an implementation of {@link Converter} which converts a 
	 * {@link String} to a {@link Character}
	 */
	public static final Converter<String, Character> CHAR = getConverterFor(Character.class);
	
	/**
	 * Returns an implementation of {@link Converter} which converts a 
	 * {@link String} to a {@link String}
	 */
	public static final Converter<String, String> STRING = getConverterFor(String.class);
	
	/**
	 * Creates a new instance of <code>StringConverters</code>
	 */
	private StringConverters() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * Returns an implementation of a {@link Converter} which can convert the 
	 * a string value to the specified destination type.
	 * 
	 * @param <T>	a type-parameter representing the destination type
	 * @param type	reference to a {@link Class} that represents the destination type
	 * 
	 * @return	an implementation of {@link Converter} which can convert a string
	 * 			value to the specified destination type
	 */
	@SuppressWarnings("unchecked")
	public static final <T> Converter<String, T> getConverterFor(Class<T> type) {
		if (!converterMap.containsKey(type))
			throw new ConverterUnavailableException("No converter found for spcified type", type);
		return (Converter<String, T>)converterMap.get(type);
	}
}
